﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JHStock.Update;
using System.IO;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using Tools;
using System.Threading;

namespace JHStock.UserForm
{
    public class FhsgsManage
    {
        public ShowDeleGate ThreadShowMsg;
        public ActionDeleGate ActionMsg;
        //private bool Isrunning;
        private JHConfig _jhconfig;
        private FhsgDatas _FDS;
        private Stocks stocks { get { return _jhconfig.Stocks; } }
        public string localFindatafile { get { return _jhconfig.Jsconfig.pathconfig.WorkPath + "AllFin.Dat"; } }
        private string localbakeFindatafile { get { return _jhconfig.Jsconfig.pathconfig.WorkPath + "AllFin.Dat_bak"; } }
        public FhsgsManage(JHConfig _jhconfig)
        {
            this._jhconfig = _jhconfig;
            _FDS = null;
            //Isrunning = false;
        }
        public void ChangeToFormatFhsg()
        {
            List<Fhsgs> ls = LoadLoacalBakeData();
            if (ls != null)
            {
                FhsgDatas FD = FhsgDatas.ToFormatFhsgFromFhsgsList(ls, stocks);
                FD.SaveFile(localFindatafile);
            }
        }
        public void DownloadAll()
        {
            int FDLatestDate = GetFDLatestDate();

            FhsgsDownLoad FD = new FhsgsDownLoad(_jhconfig, _FDS);
            FD.ThreadShowMsg = ThreadShowMsg;
            FD.DownLoad(FDLatestDate);
            ThreadShowMsg("已全部更新完毕");
        }

        private int GetFDLatestDate()
        {
            int LatestDate = 0;
            if (File.Exists(localFindatafile))
            {
                try
                {
                    if (_FDS == null)
                        _FDS = FhsgDatas.Load(localFindatafile);
                    LatestDate = _FDS.GetLatestDate();
                }
                catch
                {
                }
            }
            return LatestDate;
        }
        private List<Fhsgs> LoadLoacalBakeData()
        {
            List<Fhsgs> _ls = null;
            string _locatefindata = localbakeFindatafile;
            Msg = "";
            if (!File.Exists(_locatefindata))
            {
                Msg = "本地记录不存在";
            }
            else
                try
                {
                    _ls = JsonConvert.DeserializeObject<List<Fhsgs>>(File.ReadAllText(_locatefindata));
                    //_dic = _ls.ToDictionary(r => r.stockcode);
                }
                catch
                {
                    _ls = null;
                    Msg = "本地数据记录有误，或者格式不对，请从新下载生成";
                }
            return _ls;
        }
        public string Msg { get; set; }
    }
    public class FhsgItem
    {
        public int nd { get; set; }
        public double fh_sh { get; set; }
        public int djr { get; set; }
        public int cqr { get; set; }
        public double PX { get; set; }
        public double SG { get; set; }
        public double ZZ { get; set; }
        public string FHcontent { get; set; }
    }
    public class FhsgStock
    {
        public int index { get; set; }
        public string stockcode { get; set; }
        public List<FhsgItem> FHSG { get; set; }

        public void MergerFHSG(FhsgStock fs)
        {
            int maxdate = GetMaxDate();
            foreach (FhsgItem fi in fs.FHSG)
            {
                if (fi.cqr > maxdate)
                {
                    maxdate = fi.cqr;
                    FHSG.Add(fi);
                }
                else
                {
                    MFile.AppendAllText( "DuplyFHSG.log",stockcode + "\t"+index+"\t"+fi.nd +"\t"+fi.FHcontent +"\r\n") ;
                }
            }
        }

        private int GetMaxDate()
        {
            if (FHSG.Count == 0)
                return 0;
            return FHSG.Max(r => r.cqr);
        }
    }
    public class FhsgDatas
    {
        private Dictionary<int, FhsgStock> _dic;
        public int UpdateDate { get; set; }
        public List<FhsgStock> FhsgStocks { get; set; }
        public List<UpdateLog> UpdateLogs { get; set; }
      
        public static FhsgDatas ToFormatFhsgFromFhsgsList(List<Fhsgs> ls, Stocks stocks)
        {
            FhsgDatas fd = new FhsgDatas();
            fd.UpdateLogs = new List<UpdateLog>();
            fd.FhsgStocks = new List<FhsgStock>();
            foreach (Fhsgs s in ls)
            {
                FhsgStock fs = s.ToFormatFhsgStock();
                string numcode = s.stockcode.Substring(2);
                Stock st = stocks.StockByNumCode(numcode);
                if (st != null)
                {
                    fs.index = st.ID;
                    fd.FhsgStocks.Add(fs);
                }
            }
            fd.UpdateDate = fd.GetLatestDate();
            return fd;
        }
        public static FhsgDatas Load(string path)
        {
            FhsgDatas FD = null;
            try
            {
                if (File.Exists(path))
                {
                    string str = File.ReadAllText(path);
                    FD = JsonConvert.DeserializeObject<FhsgDatas>(str);
                }
            }
            catch
            {
                FD = null;
            }
            return FD;
        }
        public void MergerFhsgs(FhsgDatas mergerdata)
        {
            _dic = FhsgStocks.ToDictionary(r => r.index);
            foreach (FhsgStock fs in mergerdata.FhsgStocks)
            {
                if (_dic.ContainsKey(fs.index))
                {
                    _dic[fs.index].MergerFHSG(fs);
                }
                else
                {
                    FhsgStocks.Add(fs);
                    _dic[fs.index] = fs;
                }
            }

            UpdateLog ul = new UpdateLog();
            ul.BeginDate = UpdateDate;
            ul.EndDate = mergerdata.UpdateDate;
            ul.UpdateStocksCount = mergerdata.FhsgStocks.Count;
            UpdateLogs.Add(ul);

            if (UpdateDate < mergerdata.UpdateDate)
                UpdateDate = mergerdata.UpdateDate;
        }
        public int GetLatestDate()
        {
            if (FhsgStocks != null && FhsgStocks.Count > 0)
                return FhsgStocks.Max(r1 =>
                {
                    if (r1.FHSG.Count > 0)
                        return r1.FHSG.Max(r2 => r2.cqr);
                    return 0;
                });
            return 0;
        }
        public void SaveFile(string path)
        {
            MFile.WriteAllText(path, JsonConvert.SerializeObject(this));
        }
    }
    public class UpdateLog
    {
        public int BeginDate { get; set; }
        public int EndDate { get; set; }
        public int UpdateStocksCount { get; set; }
    }
    public class FHSGStrItem
    {
        /// <summary>
        /// 
        /// </summary>
        public string nd { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string fh_sh { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string djr { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string cqr { get; set; }
        /// <summary>
        /// 10派1元
        /// </summary>
        public string FHcontent { get; set; }
        public FhsgItem ToFormatItem()
        {
            FhsgItem it = new FhsgItem();
            try
            {
                it.nd = Convert.ToInt32(nd);
                it.fh_sh = 0;
                if(fh_sh!="")
                    it.fh_sh = Convert.ToDouble(fh_sh);
                it.cqr = Convert.ToInt32(cqr.Replace("-", ""));
                string sdjr = djr.Replace("-", "").Trim();
                if (sdjr != "")
                    it.djr = Convert.ToInt32(sdjr);

                Regex re = new Regex("10(派([0-9.]*)元)?(送([0-9.]*)股)?(转([0-9.]*)股)?");
                string PX = "0";
                string SG = "0";
                string ZZ = "0";
                Match m = re.Match(FHcontent);
                if (m.Success)
                {
                    if(m.Groups[2].Success)
                        PX = m.Groups[2].Value;
                    if (m.Groups[4].Success)
                        SG = m.Groups[4].Value;
                    if (m.Groups[6].Success)
                        ZZ = m.Groups[6].Value;
                }
                it.PX = Convert.ToDouble(PX);
                it.SG = Convert.ToDouble(SG);
                it.ZZ = Convert.ToDouble(ZZ);
                it.FHcontent = FHcontent;
            }
            catch
            {
                it.nd = 0;
            }
            return it;
        }
    }
    public class Fhsgs
    {
        /// <summary>
        /// 
        /// </summary>
        public string stockcode { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public List<FHSGStrItem> FHSG { get; set; }
        public FhsgStock ToFormatFhsgStock()
        {
            FhsgStock fs = new FhsgStock();
            fs.index = -1;
            fs.stockcode = stockcode;
            fs.FHSG = new List<FhsgItem>();
            foreach (FHSGStrItem s in FHSG)
                fs.FHSG.Add(s.ToFormatItem());
            return fs;
        }
    }
    public class FhsgsDownLoad
    {
        private JHConfig _jhconfig;
        private FhsgDatas _FDS;
        private StocksData DaylyStocksData { get { return _jhconfig.DaylyStocksData(); } }
        private NetDate DaylyNetdate { get { return DaylyStocksData.Netdate; } }
        private string DataPath { get { return _jhconfig.Jsconfig.pathconfig.WorkPath; } }
        public string localFindatafile { get { return DataPath + "AllFin.Dat"; } }
        public FhsgsDownLoad(JHConfig _jhconfig)
        {
            this._jhconfig = _jhconfig;
        }

        public FhsgsDownLoad(JHConfig _jhconfig, FhsgDatas _FDS)
        {
            // TODO: Complete member initialization
            this._jhconfig = _jhconfig;
            this._FDS = _FDS;
        }

        public void DownLoad(int FDLatestDate)
        {
            if (DaylyNetdate.Contains(FDLatestDate))
            {
                int daycount = DaylyNetdate.GetAfterDays(FDLatestDate, 0);
                List<Stock> list = DaylyStocksData.GetFhsgStocks(FDLatestDate);
                if (list.Count > 0)
                {
                    DownLoadFromDayly(list, daycount);
                }
                else
                {
                    ThreadShowMsg("分红数据已经最新，无需更新，最新分红除权日期 " + FDLatestDate);
                    Thread.Sleep(3000);
                }
            }
            else
            {
                int daycount = _jhconfig.Stocks.GetAfterDays(FDLatestDate);
                   DownLoadFromDayly(_jhconfig.Stocks.stocks, daycount);
            }
        }

        private void DownLoadFromDayly(List<Stock> list, int dayscount)
        {
            if (!isrunning)
            {
                this.NeedDownLoadDays = dayscount;
                isrunning = true;
                nkd = new NetKData(_jhconfig,DaylyStocksData.KdataType);
                nkd.ThreadShowMsg = ThreadShowMsg;
                nkd.CompleteRun = CompleteRun;
                nkd.DaysCount = dayscount;
                nkd.FinMode = true;
                if (true)
                {
                    nkd.SetCustomMode(true);
                    nkd.CustomDealStocks = list;
                    nkd.CompleteRun = CompleteRun;
                }
                System.Threading.Thread nonParameterThread =
                    new Thread(new ThreadStart(nkd.GetNetKData));
                nonParameterThread.Start();
            }
            while (isrunning)
                Thread.Sleep(100);
        }
        public void CompleteRun()
        {
            if (NeedDownLoadDays == _jhconfig.Stocks.ListLocalDate.Count)
            {
                List<Fhsgs>  _ls = nkd._NetObjTags.Tag.Where(r1 => r1 != null)
                    .Select(r2 => (Fhsgs)r2.ObjTag).ToList();
                _FDS = FhsgDatas.ToFormatFhsgFromFhsgsList(_ls, _jhconfig.Stocks);
                _FDS.UpdateDate = _FDS.GetLatestDate();
                _FDS.SaveFile(localFindatafile);

            }
            else
            {
                List<Fhsgs> _ls = nkd._NetObjTags.Tag.Where(r1 => r1 != null && r1.ObjTag != null)
                   .Select(r2 => (Fhsgs)r2.ObjTag).Where(r2 => r2.FHSG.Count > 0).ToList();
                if (_FDS == null)
                {
                    if (File.Exists(localFindatafile))
                    {
                        _FDS = FhsgDatas.Load(localFindatafile);
                    }
                }
                //Non Local File
                if (_FDS == null)
                {
                    _FDS = FhsgDatas.ToFormatFhsgFromFhsgsList(_ls, _jhconfig.Stocks);
                }
                else
                {
                    FhsgDatas mergerdata = FhsgDatas.ToFormatFhsgFromFhsgsList(_ls, _jhconfig.Stocks);
                    _FDS.MergerFhsgs(mergerdata);
                }
                _FDS.UpdateDate = _FDS.GetLatestDate();
                _FDS.SaveFile(localFindatafile);
            }
            ThreadShowMsg("已下载并合并所有数据");
        }
        /////forNet
        private NetKData nkd;
        private int NeedDownLoadDays; // 临时记录长度
        private bool isrunning;
        public ShowDeleGate ThreadShowMsg;

    }
}